package com.ifp.opengate.boot.gateway.formatter.template;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.PostConstruct;

import org.apache.commons.io.IOUtils;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import com.ifp.core.base.SystemConf;
import com.ifp.core.log.Trace;
import com.ifp.core.util.StringUtil;

/**
 * 报文模板
 * 
 * @author limh@belink.com
 * @since 2015-12-4 modify 灭霸 2018-10-28 springboot、可编辑模板
 * 
 */
@Component("templateContent")
@Lazy(true)
public class TemplateContent {
    private Map<String, Map<String, String>> requestTemplateMap = new HashMap<String, Map<String, String>>();
    private Map<String, Map<String, String>> responseTemplateMap = new HashMap<String, Map<String, String>>();
    /**
     * 系统配置
     */
    @Autowired
    @Qualifier("systemConf")
    private SystemConf systemConf;
    /**
     * 模板目录路径
     */
    private String templateDir = "WEB-INF/gwTemplate";
    /**
     * 配置路径
     */
    private String proFilePath = "WEB-INF/common/velocity.properties";
    /**
     * 字符编码
     */
    private String encoding = "UTF-8";
    /**
     * 模板充许大小
     */
    private int maxSize = 1024 * 1024;
    /**
     * 是否已经初始化
     */
    private boolean initFlag = false;

    @PostConstruct
    public void init() throws Exception {
        if (!initFlag) {
            FileInputStream fis = null;
            try {
                File templateDirFile = new File(templateDir);
                if (!templateDirFile.exists()) {
                    Trace.logError(Trace.MODULE_CONNECT, "load template error, file path unexists:" + templateDir);
                    return;
                }
                initTemplateMap(templateDirFile);
                // init velocity
                Properties p = null;
                if (StringUtil.hasText(proFilePath)) {
                    File f = new File(proFilePath);
                    fis = new FileInputStream(f);
                    if (f.exists()) {
                        p = new Properties();
                        p.load(fis);
                    }
                }
                if (null != p) {
                    Velocity.init(p);
                } else {
                    Properties props = new Properties();
                    props.put("resource.loader", "srs");
                    props.put("srs.resource.loader.public.name", "StringResourceLoader");
                    props.put("srs.resource.loader.class", "com.ifp.gateway.formater.template.StringResourceLoader");
                    props.put("runtime.log", "velocity.log");
                    props.put("input.encoding", encoding);
                    props.put("output.encoding", encoding);
                    props.put("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.Log4JLogChute");
                    props.put("runtime.log.logsystem.log4j.logger", "velocity");
                    props.put("log4j.logger.org.apache.velocity", "ERROR");
                    props.setProperty(Velocity.ENCODING_DEFAULT, encoding);
                    props.setProperty(Velocity.INPUT_ENCODING, encoding);
                    props.setProperty(Velocity.OUTPUT_ENCODING, encoding);
                    Velocity.init(props);
                }
                initFlag = true;
            } catch (Exception e) {
                Trace.logError(Trace.MODULE_CONNECT, "gateway template content init error!", e);
            } finally {
                if (null != fis) {
                    fis.close();
                }
            }
        }
    }

    /**
     * 获取请求模板内容
     * 
     * @param channelId
     * @param tradeCode
     * @return
     */
    public String getRequestTemplateContent(String channelId, String transCode) {
        Map<String, String> transMap = (Map)requestTemplateMap.get(channelId);
        if (null == transMap) {
            return null;
        }
        String template = transMap.get(transCode);
        // 如果接口模板为空则去系统模板
        if (null == template || "".equals(template)) {
            template = transMap.get(channelId);
        }
        return template;
    }

    /**
     * 获取响应模板内容
     * 
     * @param channelId
     * @param tradeCode
     * @return
     */
    public String getResponseTemplateContent(String channelId, String transCode) {
        Map<String, String> transMap = (Map)responseTemplateMap.get(channelId);
        if (null == transMap) {
            return null;
        }
        return transMap.get(transCode);
    }

    /**
     * 初始化模板映射
     * 
     * @param dir
     */
    private void initTemplateMap(File dirFile) {
        if (dirFile.isDirectory()) {
            File[] tfiles = dirFile.listFiles();
            for (int i = 0; i < tfiles.length; i++) {
                dirFileDataToMap(tfiles[i]);
            }
        }
    }

    /**
     * 将文件数据放入Map对象
     * 
     * @param filedir
     */
    private void dirFileDataToMap(File filedir) {
        Map<String, String> map = new HashMap<String, String>(0);
        File[] childs = filedir.listFiles();
        for (int i = 0; i < childs.length; i++) {
            if ("request".equals(childs[i].getName().toLowerCase())) {
                fileDataToMap(map, childs[i]);
                requestTemplateMap.put(filedir.getName(), map);
            } else if ("response".equals(childs[i].getName().toLowerCase())) {
                fileDataToMap(map, childs[i]);
                responseTemplateMap.put(filedir.getName(), map);
            }
        }
    }

    /**
     * 将文件数据放入Map对象
     * 
     * @param map
     * @param dir
     */
    private void fileDataToMap(Map<String, String> map, File dir) {
        File[] file = dir.listFiles();
        for (int i = 0; i < file.length; i++) {
            String fileName = file[i].getName();
            boolean b = file[i].isDirectory() || (!fileName.endsWith(".xml") && !fileName.endsWith(".json")
                && !fileName.endsWith(".txt") && !fileName.endsWith(".tpl"));
            if (b) {
                continue;
            }
            if (file[i].length() > maxSize) {
                continue;
            }

            int k;
            if ((k = fileName.lastIndexOf(".")) > 0) {
                fileName = fileName.substring(0, k);
            }
            try {
                map.put(fileName, readTxtFile(file[i]));
            } catch (IOException e) {
                Trace.logError(Trace.MODULE_CONNECT, "load template file error!", e);
            }
        }
    }

    /**
     * 读取template文件
     * 
     * @param file
     * @return
     * @throws IOException
     */
    public String readTxtFile(File file) throws IOException {
        FileInputStream fis = null;
        String data = null;
        try {
            fis = new FileInputStream(file);
            data = IOUtils.toString(fis, encoding);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            fis.close();
        }
        return data;
    }

    public String getProFilePath() {
        return proFilePath;
    }

    public void setProFilePath(String proFilePath) {
        this.proFilePath = proFilePath;
    }

    public String getTemplateDir() {
        return templateDir;
    }

    public void setTemplateDir(String templateDir) {
        this.templateDir = templateDir;
    }

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public int getMaxSize() {
        return maxSize;
    }

    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    public SystemConf getSystemConf() {
        return systemConf;
    }

    public void setSystemConf(SystemConf systemConf) {
        this.systemConf = systemConf;
    }

    public boolean isInitFlag() {
        return initFlag;
    }

    public void setInitFlag(boolean initFlag) {
        this.initFlag = initFlag;
    }

    public Map<String, Map<String, String>> getRequestTemplateMap() {
        return requestTemplateMap;
    }

    public void setRequestTemplateMap(Map<String, Map<String, String>> requestTemplateMap) {
        this.requestTemplateMap = requestTemplateMap;
    }

    public Map<String, Map<String, String>> getResponseTemplateMap() {
        return responseTemplateMap;
    }

    public void setResponseTemplateMap(Map<String, Map<String, String>> responseTemplateMap) {
        this.responseTemplateMap = responseTemplateMap;
    }

    /**
     * 添加解析模板
     * 
     * @param channelId
     * @param transCode
     * @param template
     */
    public void addResponseTemplate(String channelId, String transCode, String template) {
        this.responseTemplateMap.get(channelId).put(transCode, template);
    }

    /**
     * 添加组装模板
     * 
     * @param channelId
     * @param transCode
     * @param template
     */
    public void addRequestTemplate(String channelId, String transCode, String template) {
        this.requestTemplateMap.get(channelId).put(transCode, template);
    }

}
